package com.zhang.authoritycenter.common.util;

import com.zhang.infrastructure.model.KingHoodException;
import com.zhang.infrastructure.model.KingHoodExceptionUtil;
import com.zhang.infrastructure.model.constant.ExceptionConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

/**
 * 深圳金雅福控股集团有限公司
 *
 * @author zhangfanjun
 * @date 2021/11/17
 */
@Slf4j
public class AesUtil {

    //    public static final String ALGORITHMSTR = "AES/GCM/NoPadding";
    public static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";

    /**
     * 加密
     *
     * @author zfj
     * @date 2022/3/29
     */
    public static String encode(String key, String in) {
        //key的长度必须是16位，所以这里需要做特殊处理
        key = get16(key);
        try {
            KeyGenerator aes = KeyGenerator.getInstance("AES");
            aes.init(128);
            Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(), "AES"));
            byte[] b = cipher.doFinal(in.getBytes(StandardCharsets.UTF_8));
            // 采用base64算法进行转码,避免出现中文乱码
            return Base64Utils.encodeToString(b);
        } catch (Exception e) {
            throw new KingHoodException(ExceptionConstant.CODE_BAD_SERVER, e.getMessage());
        }
    }

    /**
     * 得到16位
     *
     * @author zfj
     * @date 2022/3/29
     */
    private static String get16(String key) {
        if (StringUtils.isEmpty(key)) {
            key = "1234567890123456";
        }
        StringBuilder sb = new StringBuilder(key);
        for (int i = 0; i < 15; i++) {
            sb.append(key);
        }
        key = sb.substring(0, 16);
        return key;
    }

    /**
     * 解密
     *
     * @author zfj
     * @date 2022/3/29
     */
    public static String decrypt(String key, String in) {
        //key的长度必须是16位，所以这里需要做特殊处理
        key = get16(key);
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128);
            Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes(), "AES"));
            // 采用base64算法进行转码,避免出现中文乱码
            byte[] encryptBytes = Base64Utils.decodeFromString(in);
            byte[] decryptBytes = cipher.doFinal(encryptBytes);
            return new String(decryptBytes);
        } catch (Exception e) {
            throw new KingHoodException(ExceptionConstant.CODE_BAD_SERVER, e.getMessage());
        }
    }


    /**
     * 加密
     */
    public static String encrypt(String content, String keyStr) {
        try {
            Cipher ex = Cipher.getInstance("AES/ECB/PKCS5Padding");
            byte[] byteContent = content.getBytes("utf-8");
            SecretKeySpec kp = new SecretKeySpec(keyStr.getBytes("utf-8"), "AES");
            ex.init(1, kp);
            byte[] result = ex.doFinal(byteContent);
            return Base64.encodeBase64String(result);
        } catch (Exception var6) {
            throw new RuntimeException(var6);
        }
    }


    /**
     * 生成签名值
     *
     * @param jsapiTicket 入参
     * @param url         入参
     * @param timestamp   入参
     * @param nonce       入参
     * @return 签名
     */
    public static String signature(String jsapiTicket, String url, String timestamp, String nonce) {
        //拼接签名参数
        log.info("###jsapiTicket:" + jsapiTicket + ";url:" + url + ";timestamp:" + timestamp + "nonce:" + nonce);
        TreeMap<String, String> treeMap = new TreeMap<>();
        treeMap.put("jsapi_ticket", jsapiTicket);
        treeMap.put("noncestr", nonce);
        treeMap.put("url", url);
        treeMap.put("timestamp", timestamp);
        StringBuilder sb = new StringBuilder();
        Iterator<Map.Entry<String, String>> it = treeMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, String> entry = it.next();
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        log.info(sb.toString().substring(0, sb.length() - 1));
        //sha1加密
        return sha1(sb.toString().substring(0, sb.length() - 1));
    }

    /**
     * @param inStr 入参
     * @return sha1签名
     * @author zfj
     * @date 2022/5/7
     */
    private static String sha1(String inStr) {
        MessageDigest md = null;
        String outStr = null;
        try {
            //选择SHA-1
            md = MessageDigest.getInstance("SHA-1");
            //返回的是byet[]，要转化为String存储比较方便
            byte[] digest = md.digest(inStr.getBytes());
            outStr = bytetoString(digest);
        } catch (NoSuchAlgorithmException nsae) {
            nsae.printStackTrace();
        }
        return outStr;
    }

    /**
     * @param digest 字节码
     * @return 字符串
     * @author zfj
     * @date 2022/5/7
     */
    public static String bytetoString(byte[] digest) {
        String str = "";
        String tempStr = "";
        for (int i = 0; i < digest.length; i++) {
            tempStr = (Integer.toHexString(digest[i] & 0xff));
            if (tempStr.length() == 1) {
                str = str + "0" + tempStr;
            } else {
                str = str + tempStr;
            }
        }
        return str.toLowerCase();
    }
}
